﻿using System.Collections.Generic;
using System.Threading.Tasks;
namespace Odyssey.Consul.Implementations
{
    using Features;
    using Http;
    using Models;
    public class KVStore : BaseConsulAPI, IKVStore
    {
        public KVStore(IHttpRequester httpRequester, IConsulConfiguration consulConfiguration) : base(httpRequester, consulConfiguration, EnumResource.Key)
        {
        }

        private string BuildKVPath(string action = "")
        {
            return BuildUri("kv", action);
        }

        private QueryParameter BuildQueryParameter(ArguKVStore arguKVStore)
        {
            QueryParameter queryParameter = null;
            if (arguKVStore != null)
            {
                queryParameter = new QueryParameter();
                if (!string.IsNullOrWhiteSpace(arguKVStore.Key))
                {
                    queryParameter.Datacenter = arguKVStore.DC;
                }
                if (arguKVStore.Recurse.HasValue)
                {
                    queryParameter.OtherParameters.Add("recurse", arguKVStore.Recurse.ToString());
                }
                if (!string.IsNullOrWhiteSpace(arguKVStore.Separator))
                {
                    queryParameter.OtherParameters.Add("separator", arguKVStore.Separator);
                }
                if (arguKVStore.Flags.HasValue)
                {
                    queryParameter.OtherParameters.Add("flags", arguKVStore.Flags.ToString());
                }
                if (arguKVStore.Cas.HasValue)
                {
                    queryParameter.OtherParameters.Add("case", arguKVStore.Cas.ToString());
                }
                if (!string.IsNullOrWhiteSpace(arguKVStore.Acquire))
                {
                    queryParameter.OtherParameters.Add("acquire", arguKVStore.Acquire);
                }
                if (!string.IsNullOrWhiteSpace(arguKVStore.Release))
                {
                    queryParameter.OtherParameters.Add("release", arguKVStore.Release);
                }
            }
            return queryParameter;
        }

        public async Task<bool> CreateAndUpdate(ArguKVStore arguKVStore)
        {
            var queryParameter = BuildQueryParameter(arguKVStore);
            var response = await ApiSendResponse(BuildKVPath(arguKVStore.Key), arguKVStore.Value, EnumConsulHttpMethod.Put, queryParameter, BuildTokenHeader());
            return (await response.Content.ReadAsStringAsync()).Contains("true");
        }

        public async Task<bool> Delete(ArguKVStore arguKVStore)
        {
            var queryParameter = BuildQueryParameter(arguKVStore);
            return (await ApiSendString(BuildKVPath(arguKVStore.Key), EnumConsulHttpMethod.Delete, queryParameter, BuildTokenHeader())).Contains("true");
        }

        public async Task<List<ResultKVStore>> Read(ArguKVStore arguKVStore)
        {
            return await ApiSend<List<ResultKVStore>>(BuildKVPath(arguKVStore.Key), EnumConsulHttpMethod.Get, BuildQueryParameter(arguKVStore), BuildTokenHeader());
        }

        public async Task<string[]> ReadByKeys(ArguKVStore arguKVStore)
        {
            var queryParameter = BuildQueryParameter(arguKVStore);
            queryParameter.OtherParameters.Add("keys", "true");
            return await ApiSend<string[]>(BuildKVPath(arguKVStore.Key), EnumConsulHttpMethod.Get, BuildQueryParameter(arguKVStore), BuildTokenHeader());
        }

        public async Task<byte[]> ReadByRaw(ArguKVStore arguKVStore)
        {
            var queryParameter = BuildQueryParameter(arguKVStore);
            queryParameter.OtherParameters.Add("raw", "true");
            var response = await ApiSendResponse(BuildKVPath(arguKVStore.Key), null, EnumConsulHttpMethod.Get, queryParameter, BuildTokenHeader());
            return await response.Content.ReadAsByteArrayAsync();
        }
    }
}
